//
//  LanguageArrayController.m
//  Words2
//
//  Created by Mathieu Tozer on 11/09/06.
//  Copyright 2006 __MyCompanyName__. All rights reserved.
//

#import "LanguageArrayController.h"
#import "LanguageMO.h"
#import "SmartGroup.h"
#import "WordMO.h"
#import "WordsAppDelegate.h"
#import "DictionaryMO.h"
#import "ControllerData.h"
#define WordType @"Word"



@implementation LanguageArrayController
- (void)awakeFromNib {
	availLangs = [[[NSMutableDictionary alloc] init] retain];
	nativeLangs = [[[NSMutableDictionary alloc] init] retain];
		// register for drag and drop
		[tableView registerForDraggedTypes:
			[NSArray arrayWithObjects:WordType, nil]];

		[super awakeFromNib];
		
		currentIndexCount = 0;
		
}


//returns a list of all the world's languages.
//These are the 'key's which are used in the 'capabilities' section of languages and dictionaries.
-(NSArray *)arrayOfSupportedLanguageCapabilities{
	NSArray *myArray = [NSArray arrayWithObjects:@"English", @"Japanese", @"Sweedish", @"French", "Portugese", "Chinese", nil]; 
	return myArray;
}

-(IBAction)addObjectFromListOfSupportedLanguages:(id)sender{
	[self supportedLanguages]; //just to refresh that silly variable. What a waste!

	NSString *languageNameToAdd = [[self selectedObjects] objectAtIndex:0];
	NSString *langPath = [availLangs objectForKey:languageNameToAdd];

	//match the selection string with the key - object in the availLang dictionary
	//decode the langage and add it to the user's managedObjectContext
	NSData *langData = [NSData dataWithContentsOfFile:langPath];
	NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:langData];
	LanguageMO *language = [NSEntityDescription insertNewObjectForEntityForName:@"Language" inManagedObjectContext:[[NSApp delegate] managedObjectContext]];
	[language setValue:[unarchiver decodeObjectForKey:@"LCapability"] forKey:@"capability"];
	[language setValue:[unarchiver decodeObjectForKey:@"LLanguageIconData"] forKey:@"languageIconData"];
	[language setValue:[unarchiver decodeObjectForKey:@"LName"] forKey:@"name"]; 
	[language setValue:[unarchiver decodeObjectForKey:@"LFirstWords"] forKey:@"firstWords"];
	[language setValue:[unarchiver decodeObjectForKey:@"LDictionariesToUseData"] forKey:@"dictionariesToUseData"];
	
	[unarchiver finishDecoding];
	
	[self createDefaultGroupsForLanguage:language];
	[self addDefaultWordsToLanguage:language];
	[self setUpDefaultDictionariesForLanguage:language];

	
	[[NSApp delegate] setMainWindowTabToMainView];
}

-(void)addDefaultWordsToLanguage:(LanguageMO*)language{
	//get the string and use the services thing to add the words as the first words or something.
}

-(void)createDefaultGroupsForLanguage:(LanguageMO*)language{
	//Create the library list
	SmartGroup *library = [NSEntityDescription insertNewObjectForEntityForName:@"SmartGroup" inManagedObjectContext:[[NSApp delegate] managedObjectContext]];
	[library setValue:language forKey:@"language"];
	[library setValue:@"Library" forKey:@"name"];
	[library setValue:[NSNumber numberWithBool:YES] forKey:@"isLibrary"];
	//set the predicate for the library smart list to ALL words in this language.
	
//can't set wordType properties anyway.	
//	//add some other useful groups to the language upon insert of new languages.
//	SmartGroup *nounList = [NSEntityDescription insertNewObjectForEntityForName:@"SmartGroup" inManagedObjectContext:[[NSApp delegate] managedObjectContext]];
//	[nounList setValue:language forKey:@"language"];
//	[nounList setValue:@"Nouns" forKey:@"name"];
//	[nounList setExtraPredicate:@"AND wordType like[c] 'n'"];
//	
//	SmartGroup *verbList = [NSEntityDescription insertNewObjectForEntityForName:@"SmartGroup" inManagedObjectContext:[[NSApp delegate] managedObjectContext]];
//	[verbList setValue:language forKey:@"language"];
//	[verbList setValue:@"Verbs" forKey:@"name"];
//	[verbList setExtraPredicate:@"AND wordType like[c] 'v'"];
//	
//	SmartGroup *adjList = [NSEntityDescription insertNewObjectForEntityForName:@"SmartGroup" inManagedObjectContext:[[NSApp delegate] managedObjectContext]];
//	[adjList setValue:language forKey:@"language"];
//	[adjList setValue:@"Adjectives" forKey:@"name"];
//	[adjList setExtraPredicate:@"AND wordType like[c] 'a'"];
	
	SmartGroup *knownList = [NSEntityDescription insertNewObjectForEntityForName:@"SmartGroup" inManagedObjectContext:[[NSApp delegate] managedObjectContext]];
	[knownList setValue:language forKey:@"language"];
	[knownList setValue:@"Known" forKey:@"name"];
	[knownList setValue:@"known == YES" forKey:@"extraPredicateString"];
//	[knownList setExtraPredicate:];
	
	SmartGroup *unknownList = [NSEntityDescription insertNewObjectForEntityForName:@"SmartGroup" inManagedObjectContext:[[NSApp delegate] managedObjectContext]];
	[unknownList setValue:language forKey:@"language"];
	[unknownList setValue:@"Unknown" forKey:@"name"];
	[unknownList setValue:@"known == NO" forKey:@"extraPredicateString"];
	
}

//This actually might be depreciated in the future anyway so I might not worry to much about the errors!
- (void)addObject:(id)language{

	[language setValue:[languageName stringValue] forKey:@"name"];
	[language setValue:[capabilitiesString stringValue] forKey:@"capability"];
	[super addObject:language];
	
	//manage the panel used to add languages
	[languageName setStringValue:@""];
	[firstLanguageInfoString setHidden:YES];
	
	[self createDefaultGroupsForLanguage:language]; //factored out the default procedures of new languages
		
	[[NSApp delegate] setMainWindowTabToMainView];

}

-(IBAction)cancelAddNewLanguage:(id)sender{
	[[NSApp delegate] setMainWindowTabToMainView];
}

-(NSNumber *)defsCounts{
	//returns an array of ints that show the number of 
	int numberOfLangs = [[self arrangedObjects] count];
	if(currentIndexCount == numberOfLangs){
		currentIndexCount = 0; //we need to start again	
	}
	
	LanguageMO *lang = [[self arrangedObjects] objectAtIndex:currentIndexCount];
	NSString *key = [lang valueForKey:@"capability"];
	WordMO *word = [[wordController selectedObjects] objectAtIndex:0];
	currentIndexCount++;
	return [NSNumber numberWithInt:[word numberOfDefsForKey:key]];
}







/*When a drag operation enters a table view, the table view sends a 
tableView:validateDrop:proposedRow:proposedDropOperation: message to 
its data source. If this method is not implemented or if the method returns 
NSDragOperationNone, the drag operation is not allowed.*/
- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)op 
{
    // Add code here to validate the drop
    NSDragOperation dragOp = NSDragOperationLink;
    
    // if drag source is self, it's a move
    if ([info draggingSource] == tableView) {
		dragOp =  NSDragOperationMove;
    }
    // we want to put the object at, not over,
    // the current row (contrast NSTableViewDropOn) 
    [tv setDropRow:row dropOperation:NSTableViewDropOn];
	
    return dragOp;   
}

/*When a validated drag operation is dropped onto a table view, 
the table view sends a tableView:acceptDrop:row:dropOperation: message to its data source. 
The data source's implementation of this method should incorporate the data from the 
dragging pasteboard (obtained from the acceptDrop parameter) and use the other parameters 
to update the table. For example, if the drag operation type (also obtained from the 
acceptDrop parameter) was NSDragOperationMove and the drag originated from the table, 
you would want to move the row from its old location to the new one.*/

- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info 
			  row:(int)row dropOperation:(NSTableViewDropOperation)operation {
	
	NSPasteboard* pboard = [info draggingPasteboard];
	NSData* rowData = [pboard dataForType:WordType];
	NSIndexSet* indexSet = [NSKeyedUnarchiver unarchiveObjectWithData:rowData];

    // if drag source is self, it's a move
	//
//    if ([info draggingSource] == tableView) { //should never actually be this 
//		
//		[DragNDropUtilities moveObjectsInArrangedObjectsFromIndexes:indexSet toIndex:row];
//		
//		// set selected rows to those that were just moved
//		// Need to work out what moved where to determine proper selection...
//		int rowsAbove = [DragNDropUtilities rowsAboveRow:row inIndexSet:indexSet];
//		
//		NSRange range = NSMakeRange(row - rowsAbove, [indexSet count]);
//		indexSet = [NSIndexSet indexSetWithIndexesInRange:range];
//		
//		[self setSelectionIndexes:indexSet];
//		
//		return YES;
//    }
	
	int	index = [indexSet lastIndex];
	LanguageMO *language = [[self arrangedObjects] objectAtIndex:row];
	WordMO *nextWord;
//warn that doing this will remove the word from this language entirely (including all manual groups)
	
	while (NSNotFound != index) {
		nextWord = [[wordController arrangedObjects] objectAtIndex:index];
		[nextWord setValue:language forKey:@"language"];
		//[nextWord setValue:nil forKey:@"manualGroups"];
		index = [indexSet indexLessThanIndex:index];
	}
	//NSArray *draggedWords = [NSKeyedUnarchiver unarchiveObjectWithData:rowData];
	
	
	//get the object at index row
	//get the lanuage object itself
	//add the dragged words to the set of words for that lanfguage.
	
	return YES;
}

#pragma mark Import / Export Dictionaries
//method which creates a bundle from the selected dictionary, archives it, and saves it as a wordsdict to a specified location.
- (IBAction)exportLanguage:(id)sender{
	int runResult;
	LanguageMO *lang = [[self selectedObjects] objectAtIndex:0];
	
	NSMutableData *data;
	NSKeyedArchiver *archiver;
	data = [NSMutableData data];
	archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
	[archiver encodeObject:[lang valueForKey:@"capability"] forKey:@"LCapability"];
	[archiver encodeObject:[lang valueForKey:@"languageIconData"] forKey:@"LLanguageIconData"];
	[archiver encodeObject:[lang valueForKey:@"name"] forKey:@"LName"];
	[archiver encodeObject:[lang valueForKey:@"firstWords"] forKey:@"LFirstWords"];
	[archiver encodeObject:[lang valueForKey:@"nativeName"] forKey:@"LNativeName"];
	
	//get the names of the dictionaries in use
	NSMutableArray *namesArray = [[NSMutableArray alloc] init];
	NSSet *dicts = [[NSApp delegate] inUseDictionariesForLanguage:lang];
	NSEnumerator *e = [dicts objectEnumerator];
	NSString *name;
	//for each of them
	while(name = [[e nextObject] valueForKey:@"name"]){
		[namesArray addObject:name];
	}
	//archive this as data into the entity
	NSData *dictNamesData = [NSKeyedArchiver archivedDataWithRootObject:namesArray];
	[lang setValue:dictNamesData forKey:@"dictionariesToUseData"];
	[archiver encodeObject:[lang valueForKey:@"dictionariesToUseData"] forKey:@"LDictionariesToUseData"];
	
	[archiver finishEncoding];
	
	NSSavePanel *panel = [NSSavePanel savePanel];
	[panel setRequiredFileType:@"wordsLang"];
	runResult = [panel runModalForDirectory:NSHomeDirectory() file:nil];
	
	/* if successful, save file under designated name */
	if (runResult == NSOKButton) {
		//data = [NSKeyedArchiver archivedDataWithRootObject:lang];
		if (![data writeToFile:[panel filename] atomically:YES])
			NSLog(@"Could Note Write to File");
	}
	
	
}
- (IBAction)importLanguage:(id)sender{
	int runResult;
	NSOpenPanel *panel = [NSOpenPanel openPanel]; //get the open panel
	[panel setAllowedFileTypes:[NSArray arrayWithObject:@"wordsLang"]];
	[panel setAllowsMultipleSelection:YES];
	runResult = [panel runModalForDirectory:NSHomeDirectory() file:@""];
	if(runResult == NSOKButton){
		NSArray *filesToOpen = [panel filenames];
		int i, count = [filesToOpen count];
        for (i=0; i<count; i++) {
            NSString *aFile = [filesToOpen objectAtIndex:i];
			NSData *langData = [NSData dataWithContentsOfFile:aFile];
			NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:langData];
			LanguageMO *lang = [NSEntityDescription insertNewObjectForEntityForName:@"Language" inManagedObjectContext:[[NSApp delegate] managedObjectContext]];
			[lang setValue:[unarchiver decodeObjectForKey:@"LCapability"] forKey:@"capability"];
			[lang setValue:[unarchiver decodeObjectForKey:@"LLanguageIconData"] forKey:@"languageIconData"];
			[lang setValue:[unarchiver decodeObjectForKey:@"LName"] forKey:@"name"]; 
			[lang setValue:[unarchiver decodeObjectForKey:@"LFirstWords"] forKey:@"firstWords"];
			[lang setValue:[unarchiver decodeObjectForKey:@"LDictionariesToUseData"] forKey:@"dictionariesToUseData"];
			[lang setValue:[unarchiver decodeObjectForKey:@"LNativeName"] forKey:@"nativeName"];
			[unarchiver finishDecoding];

			
			[self setUpDefaultDictionariesForLanguage:lang];
			[self createDefaultGroupsForLanguage:lang];
			[self addDefaultWordsToLanguage:lang];
        }
	}		
}

-(void)setUpDefaultDictionariesForLanguage:(LanguageMO*)lang{
	NSArray *dictNames = [NSKeyedUnarchiver unarchiveObjectWithData:[lang valueForKey:@"dictionariesToUseData"]];
	
	//attempt to set the language's relationships up
	//determine whether this dictionary already exists in this moc
	//set up the fetch request
	NSError *fetchError = nil; 
	NSEntityDescription *dictEntityDescription = [NSEntityDescription entityForName:@"Dictionary" inManagedObjectContext:[[NSApp delegate] managedObjectContext]]; 
	NSFetchRequest *dictRequest = [[[NSFetchRequest alloc] init] autorelease]; 
	[dictRequest setEntity:dictEntityDescription]; 
	NSEnumerator *e = [dictNames objectEnumerator];
	NSString *nextDictToTry;
	while(nextDictToTry = [e nextObject]){
		NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name LIKE[c] %@", nextDictToTry];
		[dictRequest setPredicate:predicate];
		//perform the request
		NSArray *availableDictsToThatName = [[[NSApp delegate] managedObjectContext] executeFetchRequest:dictRequest error:&fetchError]; 
		if([availableDictsToThatName count] != 0){ //we found one!
			DictionaryMO *dictToUse = [availableDictsToThatName objectAtIndex:0];
			[lang addObject:dictToUse toToManyRelationshipForKey:@"dictionaries"];
		}else{
			NSLog(@"Didn't find any dictionaries to the name of %@ in the moc", nextDictToTry);
		}
	}
}

-(void)didEnd:(NSSavePanel *)sheet
   returnCode:(int)code
  contextInfo:(void *)contextInfo{
	LanguageMO *lang = [[self selectedObjects] objectAtIndex:0];
	NSData *data;
	if(code == NSOKButton){
		data = [NSKeyedArchiver archivedDataWithRootObject:lang];
		[data writeToFile:[sheet filename] atomically:YES];
	}
}

#pragma mark 'Internal' Languages Support
//returns an array of the internally supported Dictionaries.
-(NSArray *)supportedLanguages{
	//we need to find out the user's native language, so we need the user data object
	NSError *error;
	NSMutableArray *langNames = [[NSMutableArray alloc] init];
	NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
	[fetchRequest setEntity: [NSEntityDescription entityForName:@"ControllerData" inManagedObjectContext:[[NSApp delegate] managedObjectContext]]];
	NSArray *array = [[[NSApp delegate] managedObjectContext] executeFetchRequest:fetchRequest error:&error];
	if([array count] == 0){
		NSLog(@"computer says no.");
	}
	else{
		ControllerData * myUserDataObject = [array objectAtIndex:0];
		NSString *userNativeLanguageKey = [myUserDataObject valueForKey:@"usersNativeLanguageCapabilityKey"]; //we've got to generate translations to this key
		if(userNativeLanguageKey == nil){
			//default to eng
			userNativeLanguageKey = [NSString stringWithString:@"eng"];
		}
		
		//open the folder with all the language archives in it
		NSArray *languagesPathsArray = [[NSBundle mainBundle] pathsForResourcesOfType:@"wordsLang" inDirectory:nil];
		int i, count = [languagesPathsArray count];
		for (i=0; i<count; i++) {
			NSString *aFile = [languagesPathsArray objectAtIndex:i];
			NSData *langData = [NSData dataWithContentsOfFile:aFile];
			NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:langData];
			NSMutableString *nextLangName = [[NSMutableString alloc] initWithString:[decoder decodeObjectForKey:@"LNativeName"]];
			NSString *languageKey = [decoder decodeObjectForKey:@"LCapability"];
			NSString *translation = [self translateLanguageWithKey:languageKey toLanguageWithKey:userNativeLanguageKey];
			[nextLangName appendFormat:@" (%@)", translation];
			[langNames addObject:nextLangName];
			[decoder finishDecoding];
			[availLangs setObject:aFile forKey:nextLangName];
		}
	}	
	return langNames;
}

//returns an array of supported languages with the language's name in the language's tounge
// ie nihongo for Japanese
// Italiano for Italian
-(NSArray *)nativeLanguages{
	NSArray *languagesPathsArray = [[NSBundle mainBundle] pathsForResourcesOfType:@"wordsLang" inDirectory:nil];
	NSMutableArray *langNames = [[NSMutableArray alloc] init];
	int i, count = [languagesPathsArray count];
	for (i=0; i<count; i++) {
		NSString *aFile = [languagesPathsArray objectAtIndex:i];
		NSData *langData = [NSData dataWithContentsOfFile:aFile];
		NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:langData];
		NSString *nextLangName = [decoder decodeObjectForKey:@"LNativeName"];
		[langNames addObject:nextLangName];
		NSString *keyString = [decoder decodeObjectForKey:@"LCapability"];
		[nativeLangs setObject:nextLangName forKey:keyString];
		[decoder finishDecoding];
	}
	
	return langNames;
}

-(IBAction)setNativeLanguage:(id)sender{
	NSError *error;
	NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
	[fetchRequest setEntity: [NSEntityDescription entityForName:@"ControllerData" inManagedObjectContext:[[NSApp delegate] managedObjectContext]]];
	NSArray *array = [[[NSApp delegate] managedObjectContext] executeFetchRequest:fetchRequest error:&error];
	if([array count] == 0){
		NSLog(@"computer says no.");
	}
	else{
		ControllerData * myUserDataObject = [array objectAtIndex:0];
		NSString *selectedNativeLanguage = [nativeLanguagePopUp objectValueOfSelectedItem];
		//NSString *key = [nativeLangs objectForKey:selectedNativeLanguage];
		
		[myUserDataObject setValue:selectedNativeLanguage forKey:@"usersNativeLanguage"];
		//translate this value to a capabilityKey
		NSString *key = [self keyForNativeLanguageString:selectedNativeLanguage];
		[keyLangDict release];
		[myUserDataObject setValue:key forKey:@"usersNativeLanguageCapabilityKey"];
		NSLog(@"Set Key to %@", [myUserDataObject valueForKey:@"usersNativeLanguageCapabilityKey"]);
	//	[supportedLangTableViewColumn unbind:@"value"];
		[supportedLanguagesArrayController unbind:@"contentArray"];
		[supportedLanguagesArrayController bind:@"contentArray" toObject:languageArrayController withKeyPath:@"supportedLanguages" options:nil];
	//	[supportedLangTableViewColumn bind:@"value" toObject:supportedLanguagesArrayController withKeyPath:@"arrangedObjects" options:nil];
		
	}
}

-(NSString *)keyForNativeLanguageString:(NSString *)language{
	//maintain a list of the supported languages, their native strings, and the keys that they map to
	NSMutableDictionary *mykeyLangDict = [self keyLangDict];
	return [[mykeyLangDict objectForKey:language] autorelease];
	
}

-(NSMutableDictionary *)keyLangDict{
	if(keyLangDict == nil){
		keyLangDict = [[NSMutableDictionary alloc] init];
		[keyLangDict setObject:@"eng" forKey:@"English"];
		[keyLangDict setObject:@"jpn" forKey:[NSString stringWithUTF8String:"日本語"]];
	}
	return [keyLangDict retain];
}

-(NSString *)translateLanguageWithKey:(NSString *)languageKey toLanguageWithKey:(NSString *)userNativeLanguageKey{
	//Here's were we flex some hardcore translation of language names
	NSMutableDictionary *mylanguageTranslatorDict = [self languageTranslatorDict];
	NSMutableDictionary *translatorDict = [languageTranslatorDict valueForKey:languageKey]; //this returns a dictionary that contains allll the wooorlds translations into other languages of this language's name
	NSString *translation = [translatorDict objectForKey:userNativeLanguageKey];
	[languageTranslatorDict release];
	return [translation autorelease];
	
}

// A dictionary of dictionaries. Her's the format.
//eng -> Dict2 -> fra > "Englais"
// Where no translation is available, just use the English.

-(NSMutableDictionary *)languageTranslatorDict{
	if(languageTranslatorDict == nil){ //construct the translator.
		languageTranslatorDict = [[NSMutableDictionary alloc] init];
//(eng) English
		NSMutableDictionary *engDict = [[NSMutableDictionary alloc] init];
		[engDict setObject:[NSString stringWithUTF8String:""] forKey:@"eng"]; 
		[engDict setObject:[NSString stringWithUTF8String:"英語"] forKey:@"jpn"];
		[engDict setObject:[NSString stringWithUTF8String:"Englais"] forKey:@"fre/fra"]; 
		[engDict setObject:[NSString stringWithUTF8String:"Russian"] forKey:@"rus"];
		[languageTranslatorDict setObject:engDict forKey:@"eng"]; //lock it in!
//(jpn) Japanese
		NSMutableDictionary *jpnDict = [[NSMutableDictionary alloc] init];
		[jpnDict setObject:[NSString stringWithUTF8String:""] forKey:@"jpn"];
		[jpnDict setObject:[NSString stringWithUTF8String:"Japanese"] forKey:@"eng"];
		[jpnDict setObject:[NSString stringWithUTF8String:"Japones"] forKey:@"fre/fra"];		
		[jpnDict setObject:[NSString stringWithUTF8String:"Jrapjdfsp"] forKey:@"rus"];
		[languageTranslatorDict setObject:jpnDict forKey:@"jpn"]; //lock it in!
//(rus) Russian
		NSMutableDictionary *rusDict = [[NSMutableDictionary alloc] init];
		[rusDict setObject:[NSString stringWithUTF8String:""] forKey:@"rus"];
		[rusDict setObject:[NSString stringWithUTF8String:"Russian"] forKey:@"eng"];
		[rusDict setObject:[NSString stringWithUTF8String:"Russionaire"] forKey:@"fre/fra"];	
		[rusDict setObject:[NSString stringWithUTF8String:"ロシア語"] forKey:@"jpn"];	
		[languageTranslatorDict setObject:rusDict forKey:@"rus"]; //lock it in!		
//(fre/fra) French
		NSMutableDictionary *frefraDict = [[NSMutableDictionary alloc] init];
		[frefraDict setObject:[NSString stringWithUTF8String:""] forKey:@"fre/fra"];
		[frefraDict setObject:[NSString stringWithUTF8String:"French"] forKey:@"eng"];
		[frefraDict setObject:[NSString stringWithUTF8String:"Rofuufufufa"] forKey:@"rus"];	
		[frefraDict setObject:[NSString stringWithUTF8String:"フランス語"] forKey:@"jpn"];	
		[languageTranslatorDict setObject:frefraDict forKey:@"fre/fra"]; //lock it in!	
			
	}
	return [languageTranslatorDict retain];
}




@end
